package uiUtil;

import java.util.ArrayList;
import java.util.List;

import javax.swing.DefaultListSelectionModel;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.table.AbstractTableModel;

public abstract class AbstractEditableCustomTable <T> extends JTable implements
		CustomTableIF <T> {
	
	private class CustomTableModel extends AbstractTableModel {
		
		private List<T> model = new ArrayList<>();
		private String[] colNames = {};
		
		public void setModel(List<T> model) {
			
			//System.out.println("AbstractCustomTable.CustomTableModel.setModel()");
			this.model = model;
			super.fireTableDataChanged();
			
		}
		
		public void setColNames(String[] colNames) {
			
			this.colNames = colNames;
			super.fireTableStructureChanged();
			
		}
		
		@Override
		public String getColumnName(int column) {
			
			//System.out.println("AbstractCustomTable.CustomTableModel.getColumnName(" + column + ")");
			return this.colNames[column];
			
		}

		@Override
		public int getColumnCount() {
			
			//System.out.println("AbstractCustomTable.CustomTableModel.getColumnCount() --> " + colNames.length);
			return this.colNames.length;
			
		}

		@Override
		public int getRowCount() {
			
			//System.out.println("AbstractCustomTable.CustomTableModel.getRowCount() --> " + model.size() );
			return this.model.size();
			
		}

		@Override
		public Object getValueAt(int row, int col) {
			
			//System.out.println("AbstractCustomTable.CustomTableModel.getValueAt(" + row + ", " + col + ")");
			return getCellValue(col, this.model.get(row));
			
		}

		public T getObjectByIndex(int row) {
			
			return this.model.get(row);
			
		}
		
		@Override
		public Class<?> getColumnClass(int columnIndex) {
			
			//return doGetColumnClass(columnIndex);
			return getValueAt(0, columnIndex).getClass();
			
		}
		
		@Override
		public boolean isCellEditable(int rowIndex, int columnIndex) {
			
			return doIsCellEditable(rowIndex, columnIndex);
			
		}
		
		@Override
		public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
			
			doSetValueAt(aValue, columnIndex, this.model.get(rowIndex));		
			fireTableCellUpdated(rowIndex, columnIndex);
		
		}
		
	}
	
	private CustomTableModel tableModel;
	
	
	public AbstractEditableCustomTable() {
		
		this.tableModel = new CustomTableModel();
		this.setModel(this.tableModel);
		super.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
		
	}
	
	public List<T> getDataModel() {
		
		return this.tableModel.model;
		
	}
	
	public abstract boolean doIsCellEditable(int rowIndex, int columnIndex);

	//public abstract Class<?> doGetColumnClass(int columnIndex);

	public abstract void doSetValueAt(Object aValue, int columnIndex, T t);

	@Override
	public final void setModel(List<T> objectList) {
		
		this.tableModel.setModel(objectList);
		
	}

	
	public abstract Object getCellValue(int col, T o);

	@Override
	public final void setColNames(String... colNames) {
		
		this.tableModel.setColNames(colNames);
		
	}

	@Override
	public final T getSelectedObject() {
		
		int row = getSelectedRow();
		if (row < 0) {
			return null;
		}
		return this.tableModel.getObjectByIndex(row);
		
	}
	
}
